import java.util.ArrayList;

/**
 * Classe que representa uma composição ferroviária.
 * Uma composição é um conjunto de locomotiva(s) e
 * vagões conectados para para fazer uma viagem.
 *
 */
public class Composicao {

	/**
	 * Variável usada para representar os carros desta composição
	 */
	private ArrayList<Carro> carros;
	
	/**
	 * Variável usada para armazenar o código
	 */
	private String codigo;
	
	/* DONE inicializar variáveis internas */
	//construtor da Classe Composicao
	public Composicao(String codigo) {
		this.codigo = codigo;
		this.carros = new ArrayList<Carro>();
	}
	
	/* DONE retornar tamanho da composição */
	public int tamanhoComposicao() {
		return this.carros.size();
	}
	
	/* DONE retornar carro na posição indicada */
	public Carro getCarro(int carro) {
		return this.carros.get(carro);
	}
	
	/* DONE adicionar um carro na composição (usar atributos "carros")
	 * - Se carro for locomotiva, inserir no início (posição 0) e dar um shift no restante do vetor
	 * - Senão, inserir no final
	 */
	public void adicionaCarro(Carro carro) {
		int ultimo= this.carros.size();		
		if(carro instanceof Locomotiva){
		//verifica se o vetor esta vazio antes de dar um shift
			if(!this.carros.isEmpty()){
				//aumentar a capacidade do vetor em uma posição para deslocar o último elemento para uma nova posição
				ultimo ++;
				carros.ensureCapacity(ultimo);
				//shift de todos os elementos
				System.arraycopy(carros, 0, carros, 1, carros.size());
				this.carros.add(0, carro);//adiciona locomotiva na posição inicial	
			}
			else this.carros.add(0, carro);//carros esta vazio e carro é uma instância de Locomotiva
			
		}
		else{//é um vagão
			if(!this.carros.isEmpty()){
				ultimo ++;
				carros.ensureCapacity(ultimo);
				this.carros.add(ultimo, carro);//adciona na última posição
			}
			else this.carros.add(carro);//estava vazio o vetor e adicionou na primeira posição sem preocupação
			//pois na entrada de uma locomotiva, esta será tratada e colocada na primeira posição do vetor,
			//assim como o vetor será deslocado
		}
	}
	
	/* DONE retornar true se composição for válida, false caso contrário
	 * Composição é válida se possuir pelo menos uma locomotiva
	 */
	public boolean valida () {
		for(Carro valido: carros){
			if(valido instanceof Locomotiva) return true;
		}
		return false;
	}
	
	/* DONE retornar soma das capacidades dos vagões de líquidos nesta composição */
	public double capacidadeTotalLiquidos() {
		double capacidadetotalliquidos = 0;
		for(Carro vagaoliquidos: carros){
			if(vagaoliquidos instanceof VagaoLiquidos){
				//downcasting
				VagaoLiquidos vagaoliq = (VagaoLiquidos)vagaoliquidos;
				capacidadetotalliquidos =+ vagaoliq.getCapacidade();
				//não existe confusão após downcasting o compilador sabe que o getCapacidade() é de VagaoLiquidos!
			}//fim do if
		}//fim do for
		return capacidadetotalliquidos;
	}
	
	/* DONE retornar soma das capacidades de vagões graneleiros nesta composição */
	public double capacidadeTotalGraneis() {
		double capacidadetotalgraneis = 0;
		for(Carro vagaograneleiro: carros){
			if(vagaograneleiro instanceof VagaoGraneleiro){
				//downcasting
				VagaoGraneleiro vagaogranel = (VagaoGraneleiro)vagaograneleiro;
				capacidadetotalgraneis =+ (double)vagaogranel.getCapacidade();
				//não existe confusão após downcasting o compilador sabe que o getCapacidade() é de VagaoGraneleiro! 
			}
		}
		return capacidadetotalgraneis;
	}
	
	/* DONE retornar true se esta composição é inflamável, false caso contrário
	 * Composição é inflamável se  existir pelo menos um vagão que possa
	 * carregar líquidos inflamáveis
	 */
	public boolean inflamavel() {
		for(Carro vagaoliquidos: carros){
			if(vagaoliquidos instanceof VagaoLiquidos){
				//downcasting
				VagaoLiquidos vagaoliq = (VagaoLiquidos)vagaoliquidos;
				if(vagaoliq.inflamavel()) return true;//encontrou pelo menos um inflamável				
			}//fim do laço for
		}
		return false;//percorre todos os vagões e não encontrou nenhum inflamável
	}
	
	/**
	 * Retorna a representação desta composição como String.
	 */
	public String toString() {
		String retorno = codigo + "|" + capacidadeTotalLiquidos() + "|" +
				capacidadeTotalGraneis() + "|";
		for (Carro carro : carros) {
			retorno = retorno + carro.getCodigo() + "|"; 
		}
		return retorno;
	}
}
